package com.violet.uaa.server.security.filter;

import cn.hutool.core.util.ObjectUtil;
import com.violet.common.constant.business.CodeEnum;
import com.violet.common.constant.universal.SecurityConstants;
import com.violet.common.util.ResponseUtil;
import com.violet.redis.constant.RedisKeyPrefixConstant;
import com.violet.redis.constant.RedisKeyUtil;
import com.violet.redis.template.RedisRepository;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 类说明: 对登陆的图片验证码/短信验证码等做校验的过滤器该过滤器
 * 该过滤器在用户信息校验前（UsernamePasswordAuthenticationFilter）做校验
 *
 * @author wqf
 * @date 2023/7/8 23:08
 */
@Slf4j
@Component
public class SecurityCaptchaFilter extends OncePerRequestFilter {

    @Resource
    private RedisRepository redisRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                    @NotNull HttpServletResponse response,
                                    @NotNull FilterChain filterChain) throws ServletException, IOException {
        //pc登录验证码校验
        if (SecurityConstants.LOGIN_URL.equals(request.getServletPath())) {
            //验证码判空校验
            String code = request.getParameter("code");
            if (!StringUtils.hasLength(code)) {
                log.warn("登录请求====验证码为空");
                ResponseUtil.errorResponse(response, CodeEnum.VERIFICATION_CODE_EMPTY, "验证码不能为空",
                        HttpStatus.INTERNAL_SERVER_ERROR);
                return;
            }
            String codeKey = request.getParameter("codeKey");
            if (!StringUtils.hasLength(codeKey)) {
                log.warn("登录请求====验证码唯一标识为空");
                ResponseUtil.errorResponse(response, CodeEnum.INVALID_REQUEST, "无效请求", HttpStatus.INTERNAL_SERVER_ERROR);
                return;
            }
            String captchaCacheKey = RedisKeyUtil.getCacheKey(RedisKeyPrefixConstant.Validate.VALIDATE_IMG_KEY, codeKey);
            if (ObjectUtil.isEmpty(redisRepository.get(captchaCacheKey))) {
                log.warn("登录请求====验证码已过期");
                ResponseUtil.errorResponse(response, CodeEnum.VERIFY_HAS_EXPIRED, "验证码已过期", HttpStatus.INTERNAL_SERVER_ERROR);
                return;
            }
            String captchaCacheValue = String.valueOf(redisRepository.get(captchaCacheKey));
            if(!captchaCacheValue.equalsIgnoreCase(code)){
                log.warn("登录请求====验证码错误");
                ResponseUtil.errorResponse(response, CodeEnum.VERIFICATION_CODE_ERROR, "验证码错误", HttpStatus.INTERNAL_SERVER_ERROR);
                return;
            }
            log.info("登录请求====验证码校验通过");
        }
        filterChain.doFilter(request, response);
    }
}
